/*
 *  Copyright 2006 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.persistence.hibernate.forum;

import com.blandware.atleap.model.core.ContentLocale;
import com.blandware.atleap.model.core.User;
import com.blandware.atleap.model.forum.Forum;
import com.blandware.atleap.model.forum.Post;
import com.blandware.atleap.model.forum.ForumSubscription;
import com.blandware.atleap.persistence.forum.ForumDAO;
import com.blandware.atleap.persistence.forum.ForumSubscriptionDAO;
import com.blandware.atleap.persistence.forum.PostDAO;
import com.blandware.atleap.persistence.hibernate.util.DeleteProcessor;
import com.blandware.atleap.common.util.QueryInfo;
import com.blandware.atleap.common.util.PartialCollection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.event.DeleteEvent;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContext;
import org.springframework.beans.BeansException;

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

/**
 * <p>Processes entity deletions to handle forum module associations.
 * </p>
 * <p><a href="ForumModuleDeleteProcessor.java.html"><i>View source</i></a></p>
 *
 * @author Roman Puchkovskiy <a href="mailto:roman.puchkovskiy@blandware.com">
 *         &lt;roman.puchkovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.2 $ $Date: 2006/10/03 13:47:37 $
 */
public class ForumModuleDeleteProcessor
        implements DeleteProcessor, ApplicationContextAware {

    /**
     * Logging instance
     */
    protected transient final Log log = LogFactory.getLog(ForumModuleDeleteProcessor.class);

    /**
     * Application context
     */
    protected ApplicationContext applicationContext;
    /**
     * DAO to work with forums
     */
    protected ForumDAO forumDAO = null;
    /**
     * DAO to work with posts
     */
    protected PostDAO postDAO = null;
    /**
     * DAO to work with forum subscriptions
     */
    protected ForumSubscriptionDAO forumSubscriptionDAO = null;
    /**
     * Name of bean representing forum DAO
     */
    protected String forumDAOBeanName;
    /**
     * Name of bean representing post DAO
     */
    protected String postDAOBeanName;
    /**
     * Name of bean representing forum subscription DAO
     */
    protected String forumSubscriptionDAOBeanName;

    /**
     * Sets application context.
     *
     * @param applicationContext context to set
     * @throws BeansException
     */
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Sets name of bean representing forum DAO.
     *
     * @param forumDAOBeanName bean name
     */
    public void setForumDAOBeanName(String forumDAOBeanName) {
        this.forumDAOBeanName = forumDAOBeanName;
    }

    /**
     * Sets name of bean representing post DAO.
     *
     * @param postDAOBeanName bean name
     */
    public void setPostDAOBeanName(String postDAOBeanName) {
        this.postDAOBeanName = postDAOBeanName;
    }

    /**
     * Sets name of bean representing forum subscription DAO.
     *
     * @param forumSubscriptionDAOBeanName bean name
     */
    public void setForumSubscriptionDAOBeanName(
            String forumSubscriptionDAOBeanName) {
        this.forumSubscriptionDAOBeanName = forumSubscriptionDAOBeanName;
    }

    /**
     * Processes entity deletion.
     *
     * @param event event occured
     */
    public void processDelete(DeleteEvent event) {

        if (forumDAO == null) {
            initialize();
        }

        Object entity = event.getObject();
        if (entity instanceof ContentLocale) {
            // If locale is deleted, deleting all forums for that locale first
            ContentLocale contentLocale = (ContentLocale) entity;

            Map queryParameters = new HashMap();
            queryParameters.put("ignoreParent", Boolean.TRUE);

            QueryInfo queryInfo = new QueryInfo();
            queryInfo.setWhereClause("f.language.identifier = '"
                    + contentLocale.getIdentifier() + "'");
            queryInfo.setQueryParameters(queryParameters);

            PartialCollection collection = forumDAO.listForums(queryInfo);
            for (Iterator i = collection.iterator(); i.hasNext(); ) {
                Forum forum = (Forum) i.next();
                forumDAO.deleteForum(forum);
            }
        } else if (entity instanceof User) {
            // If user is deleted, deleting all forum subscriptions for this
            // user and making his posts to lose their connection to author user
            User user = (User) entity;
            QueryInfo queryInfo;

            queryInfo = new QueryInfo();
            queryInfo.setQueryParameters(new HashMap());
            queryInfo.setWhereClause("post.authorUser.name = '"
                    + user.getName() + "'");
            PartialCollection posts = postDAO.listPosts(queryInfo);
            for (Iterator i = posts.iterator(); i.hasNext(); ) {
                Post post = (Post) i.next();
                post.setAuthorUser(null);
                postDAO.updatePost(post);
            }

            queryInfo = new QueryInfo();
            queryInfo.setQueryParameters(new HashMap());
            queryInfo.setWhereClause("fs.user.name = '" + user.getName() + "'");
            PartialCollection subscriptions
                    = forumSubscriptionDAO.listForumSubscriptions(queryInfo);
            for (Iterator i = subscriptions.iterator(); i.hasNext(); ) {
                ForumSubscription subscription = (ForumSubscription) i.next();
                forumSubscriptionDAO.deleteForumSubscription(subscription);
            }
        }
    }

    /**
     * Initializes object.
     */
    protected void initialize() {
        forumDAO = (ForumDAO) applicationContext.getBean(forumDAOBeanName);
        postDAO = (PostDAO) applicationContext.getBean(postDAOBeanName);
        forumSubscriptionDAO = (ForumSubscriptionDAO) applicationContext.getBean(forumSubscriptionDAOBeanName);
    }
}
